﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Smart Text 帮助文件</title>
    <style type="text/css">
        span
        {
            color: #BDAE9D;
        }
        .sc0
        {
            color: #FFFFFF;
        }
        .sc4
        {
            color: #FF3A83;
        }
        .sc6
        {
            color: #80FF80;
        }
        .sc16
        {
            font-weight: bold;
            color: #00FF80;
        }
        .sc17
        {
            color: #FF8040;
        }
        .sc24
        {
        }
        .sc99
        {
            font-family: Courier New;
            background: #000000;
            color: #66CCFF;
        }
        .detail
        {
            font-size: small;
            font-family: Courier New;
            background: #AfAfAf;
        }
        .error
        {
            font-family: Courier New;
            background: #AfAfAf;
            color: #FF0000;
        }
    </style>
</head>
<body>
    <div id="main">
        <div id="navigation">
            <h1>
                Smart Text</h1>
            <ul>
                <li><a href="#intro">简介</a></li>
                <li><a href="#getting started">开始</a></li>
                <li><a href="#template">模板</a>
                    <ul>
                        <li><a href="#variable">变量</a></li>
                        <li><a href="#control">流程控制</a>
                            <ul>
                                <li><a href="#if">if</a></li>
                                <li><a href="#for">for</a></li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li><a href="#parameter">参数</a>
                    <ul>
                        <li><a href="#csv">CSV参数文件</a></li>
                        <li><a href="#xml">XML参数文件</a></li>
                        <li><a href="#lua">LUA参数文件</a></li>
                    </ul>
                </li>
                <li><a href="#error handling">错误处理</a>
                    <ul>
                        <li><a href="#lua error">Lua错误</a></li>
                        <li><a href="#undefine variable">未定义变量错误</a></li>
                    </ul>
                </li>
                <li><a href="#command line">命令行参数</a></li>
                <!--<li><a href="#useltt">在代码中使用LuaTextTemplate</a></li>-->
                <!--<li><a href="#about">关于</a></li>-->
            </ul>
        </div>
    </div>
    <br />
    <hr />
    <div id="content">
        <h2>
            <a name="intro">简介</a></h2>
        <p>
                    Smart Text是一个文本生成工具.<br />
        使用它可以帮助你用极少的时间快速生成大量文本(比如代码,报表,配置文件等等,本帮助文件就是使用SmartText生成的).<br />
        它内置了一个名为LuaTextTemplate的文本模板引擎(类似Velocity), 并提供了一个漂亮,简单易用的GUI让你更好地使用它.
    
        </p>
        <br />
        <br />
                主要特点:<ul>
        <li>使用简单的Lua语法构建模板(非常灵活!)</li>
        <li>支持3种类型的参数文件</li>
        <ul>
            <li>.csv</li>
            <li>.xml</li>
            <li>.lua</li>
        </ul>
        <li>支持命令行参数</li>
        <li>多语言支持(包括英语,简体中文,日语)</li>
        <li>友好的GUI</li>
        </ul>
    
        <br />
        <br />
        <hr />
        <h2>
            <a name="getting started">开始</a></h2>
        <p>
                    Smart Text需要运行在Windows XP/Vista/7及以上的操作系统.<br />
        并需要安装.Net Framework 4.0及以上.<br />
        双击SmartText.exe即可运行.<br />
    
        </p>
        <img src="Images/mainui_chinese.jpg" /><br />
        <p>
                    界面还算漂亮吧?好,那么让我们用一个简单的例子来看看Smart Text能干些什么.
    </p>
        <ul>
            <li>        制作模板文件<br />
        用你喜欢的文本编辑器输入下面的文本,并保存为template.txt(文件位置任意).<br />
    
                <br />
                <div class="sc99">
                    <span class="sc0">Hello</span><span class="sc24"> </span><span class="sc16">${person.name}</span><span
                        class="sc0">!</span><span class="sc24">
                            <br />
                        </span><span class="sc0">This</span><span class="sc24"> </span><span class="sc0">year</span><span
                            class="sc24"> </span><span class="sc16">${person.name}</span><span class="sc24">
                    </span><span class="sc0">is</span><span class="sc24"> </span><span class="sc16">${person.age}</span><span
                        class="sc24"> </span><span class="sc0">years</span><span class="sc24"> </span>
                    <span class="sc0">old.</span><span class="sc24"><br />
                    </span><span class="sc0">Next</span><span class="sc24"> </span><span class="sc0">year</span><span
                        class="sc24"> </span><span class="sc16">${person.name}</span><span class="sc24">
                    </span><span class="sc0">is</span><span class="sc24"> </span><span class="sc16">${person.age+1}</span><span
                        class="sc24"> </span><span class="sc0">years</span><span class="sc24"> </span>
                    <span class="sc0">old.</span></div>
                <br />
            </li>
            <li>        制作参数文件<br />
        同样,用文本编辑器输入下面的文本,并保存为parameter.xml(文件位置任意).<br />
    
                <br />
                <div class="sc99">
                    &lt;person&gt;<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;<span class="sc0">WAKU</span>&lt;/name&gt;<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&lt;age&gt;<span class="sc0">29</span>&lt;/age&gt;<br />
                    &lt;/person&gt;<br />
                </div>
                <br />
            </li>
            <li>        使用Smart Text<br />
        在"模板文件"中选择保存的template.txt文件,<br />
        在"参数文件"中选择parameter.xml文件,<br />
        "输出文件"为空即可,<br />
        点击"生成"按钮,如果一切正常的话,你将会看到下面的输出文本:<br />
    
                <img src="Images/sample_result_chinese.jpg" /><br />
            </li>
        </ul>
        <p>
                    怎么样,聪明的你应该能猜到Smart Text大概的本领了吧?
    </p>
        <br />
        <br />
        <hr />
        <h2>
            <a name="template">模板</a></h2>
        <p>
                    SmartText的模板是生成文本的框架.<br />
        模板中使用一些特殊的标记来区分哪些是普通文本,哪些是要特殊处理的内容.<br />
        SmartText主要使用Lua语法做为模板的控制语法,<br />
        所以如果你熟悉Lua的话,你会非常容易的就能掌握SmartText的模板文件<br />
        如果不太熟悉Lua的话也不要紧,只需要学习几种非常简单的结构就能做出符合自己要求的模板文件来.<br />
    
        </p>
        <h3>
            <a name="variable">变量</a></h3>
        <p>
                    通过<a href="#getting started">开始</a>中的例子,你应该已经知道了SmartText的模板使用变量的语法:<br />
    
        </p>
        <div class="sc99">
            <span class="sc16">${<i>表达式</i>}</span>
        </div>
        <br />
        <p>
                    只要是一个合法的Lua表达式,SmartText就会计算该表达式的结果,并用结果替换变量出现的位置.<br />
        利用Lua的特性,可以很容易为一个变量设置一个默认值,比如:<br />
    
        </p>
        <div class="sc99">
            <span class="sc16">${person.name or 'somebody'}</span>
        </div>
        <br />
        <p>
                    当person.name为nil(Lua中表示空值)时,则使用or后面的值(一个字符串somebody).<br />
        另外Lua中使用字符串,既可以使用双引号("),也可以使用单引号(').<br />
        <br />
        之前的例子都展示了一个很重要的用法,即使用点(.)来表示参数的层级结构.<br />
        在<a href="#parameter">参数</a>中我们还会详细讲解<br />
    
        </p>
        <h3>
            <a name="control">流程控制语句</a></h3>
        <p>
                    模板中可以使用判断语句(if)或者是循环语句(for)来控制文本生成的方式.<br />
        因为SmartText内部使用Lua(最终模板会被解析成Lua代码),所以流程控制语句都是使用标准的Lua语法.<br />
        唯一特别的是,需要使用#{...}的方式:<br />
    
        </p>
        <div class="sc99">
            <span class="sc17">#{<i>Lua语句</i>}</span>
        </div>
        <br />
        <h4>
            <a name="#if">if</a></h4>
        <p>
                    看下面的例子:
    <br />
        </p>
        <div class="sc99">
            <span class="sc17">#{if person.age &lt; 18 then}<br />
            </span><span class="sc16">${person.name}</span><span class="sc24"> </span><span
                class="sc0">is</span><span class="sc24"> </span><span class="sc0">a</span><span class="sc24">
                </span><span class="sc0">child.<br />
                </span><span class="sc17">#{else}<br />
                </span><span class="sc16">${person.name}</span><span class="sc24"> </span><span
                    class="sc0">is</span><span class="sc24"> </span><span class="sc0">an</span><span
                        class="sc24"> </span><span class="sc0">adult.<br />
                        </span><span class="sc17">#{end}</span></div>
        <br />
        <p>
                    该例子中,使用if语句根据年龄在child和adult中做出判断.<br />
        使用之前的xml参数的话,该示例的输出结果为:<br />
    
        </p>
        <div class="sc99">
            WAKU is an adult.
        </div>
        <br />
        <p>
                    Lua中if语句完整的语法是这样:
    
        </p>
        <div class="sc99">
            stat ::= if exp then block {elseif exp then block} [else block] end
        </div>
        <p>
                    当然在判断条件中也可以使用Lua中的运算符,下面是运算符的一个表格:
    
			</p>
            <table border="1" cellpadding="2" style="border-collapse: collapse" bordercolor="#111111">
                <tr align="center">
                    <td>
                                运算符
    
                    </td>
                    <td>
                                含义
    
                    </td>
                </tr>
                <tr align="center">
                    <td>
                        ==
                    </td>
                    <td>
                                相等
    
                    </td>
                </tr>
                <tr align="center">
                    <td>
                        ~=
                    </td>
                    <td>
                                不等
    
                    </td>
                </tr>
                <tr align="center">
                    <td>
                        &lt
                    </td>
                    <td>
                                小于
    
                    </td>
                </tr>
                <tr align="center">
                    <td>
                        &gt
                    </td>
                    <td>
                                大于
    
                    </td>
                </tr>
                <tr align="center">
                    <td>
                        &lt=
                    </td>
                    <td>
                                小于等于
    
                    </td>
                </tr>
                <tr align="center">
                    <td>
                        &gt=
                    </td>
                    <td>
                                大于等于
    
                    </td>
                </tr>
                <tr align="center">
                    <td>
                        and
                    </td>
                    <td>
                                与
    
                    </td>
                </tr>
                <tr align="center">
                    <td>
                        or
                    </td>
                    <td>
                                或
    
                    </td>
                </tr>
                <tr align="center">
                    <td>
                        not
                    </td>
                    <td>
                                非
    
                    </td>
                </tr>
            </table>
            <h4>
                <a name="#for">for</a></h4>
            <p>
                        使用for语句,可循环输出模板中的一部分,在输出重复内容,列表等文本时极为有用.<br />
        Lua中的for有两种,我们先看第一种:数值型for
    </p>
            <div class="sc99">
                <span class="sc17">#{for i = 1, 5 do}<br />
                </span><span class="sc0">i = </span><span class="sc16">${i}</span><br />
                <span class="sc17">#{end}</span></div>
            <br />
            <p>
                        这个模板是如此简单甚至都不需要使用参数文件就能输出结果:<br />
    
            </p>
            <div class="sc99">
                i = 1<br />
                i = 2<br />
                i = 3<br />
                i = 4<br />
                i = 5
            </div>
            <br />
            <p>
                        数值型for的语法是这样:
    </p>
            <div class="sc99">
                stat ::= for Name `=´ exp1 `,´ exp2 [`,´ exp3] do block end
            </div>
                    其中exp1是初始值,exp2是终止值,exp3是步进值,省略时默认值为1
    
            <p>
                        然而在实际工作中,我们经常使用的是另一种for:范型for<br />
        演示范型for之前我们需要先扩展我们的参数文件:
    
            </p>
            <div class="sc99">
                &lt;list&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&lt;person&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;<span class="sc0">WAKU</span>&lt;/name&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;age&gt;<span class="sc0">29</span>&lt;/age&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&lt;/person&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&lt;person&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;<span class="sc0">Joey</span>&lt;/name&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;age&gt;<span class="sc0">2</span>&lt;/age&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&lt;/person&gt;<br />
                &lt;/list&gt;</div>
            <br />
            <p>
                        然后在模板中像下面这样使用范型for:
    
            </p>
            <div class="sc99">
                <span class="sc17">#{for p in enum(list.person) do}</span><br />
                <span class="sc24"></span><span class="sc0">NAME:</span><span class="sc24"> </span>
                <span class="sc16">${p.name}</span><span class="sc24"> </span><span class="sc0">AGE:</span><span
                    class="sc24"> </span><span class="sc16">${p.age}</span><span class="sc24"><br />
                    </span><span class="sc17">#{end}</span></div>
            <br />
            <p>
                        输出结果为:
    </p>
            <div class="sc99">
                NAME: WAKU AGE: 29<br />
                NAME: Joey AGE: 2
            </div>
            <br />
            <p>
                        SmartText将XML参数的解析成Lua代码,(将在<a href="#parameter">参数</a>中详细讲解)其中的person是一个Table(可做为数组),通过list.person来引用它.<br />
        SmartText提供了一个非常方便的函数enum,用来枚举Table中的元素,<br />
        所以enum(list.peronson)就是枚举数组中所有person,每次的枚举结果用p表示.<br />
    <p>
                <br />
                <div class="detail">
                    <ul>
                                <li>技术细节:</li><br />
        enum是SmartText提供的一个函数,并不是Lua的标准函数,<br />
        enum不仅可以枚举Lua的数组形式的Table,还可以枚举.Net数组,集合(List, Dictionary等)和所有实现了IEnumerable接口的对象,<br />
        当枚举Lua的Table时,与Lua函数ipairs类似,不同的地方是,ipairs函数返回两个值(索引和值),而enum只返回值.<br />
        关于enum函数的具体实现,可查看SmartText的源代码
    
                    </ul>
                </div>
            </p>
            <p>
                        最后,提供范型for的语法:
    </p>
            <div class="sc99">
                stat ::= for namelist in explist do block end
            </div>
            <p>
                        以上就是关于流程控制的讲解,主要是if和for,但是SmartText与Lua结合的非常灵活,<br />
        实际上你可以在#{...}中插入任意有效的Lua语句,它们都将成为Lua代码并被执行.<br />
        你可以在#{...}中定义全局变量,并在模板的其它位置使用它.<br />
        你甚至可以定义函数,以此实现类似velocity中的宏.
    </p>
            <br />
            <br />
            <hr />
            <h2>
                <a name="parameter">参数</a></h2>
            <p>
                        SmartText可以使用三种类型的参数文件(CSV XML LUA),虽然它们作用类似(都是向模板提供数据),<br />
        但是每种类型都有各自的优缺点,应当在不同场合使用合适的参数文件类型.<br />
        SmartText把CSV和XML参数文件都解析为Lua代码,但是不需要掌握解析的细节,只需要知道如何在模板中正确的使用数据即可.
    
            </p>
            <a name="csv">CSV参数文件</a>
            <p>
                        CSV参数文件是最简单的参数文件,数据关系简单明了.可以使用EXCEL编辑CSV文件.<br />
        行列格式也和数据库中的表对应,所以如果想以数据库中的一个表做为参数的话,CSV参数文件是最合适不过的了.<br />
        但是CSV参数文件不能表示有层级关系的数据结构,这时就需要考虑使用XML和LUA形式的参数文件了.
    
            </p>
            <h3>
                        示例:
    </h3>
            <p>
                        模板文件:
    </p>
            <div class="sc99">
                <span class="sc16">${parameter[1].name}</span><span class="sc24"> </span><span class="sc0">
                    is</span><span class="sc24"> </span><span class="sc16">${parameter[1].age}</span><span
                        class="sc24"> </span><span class="sc0">years</span><span class="sc24"> </span>
                <span class="sc0">old.</span><br />
                <span class="sc24"></span><span class="sc16">${parameter[2].name}</span><span class="sc24">
                </span><span class="sc0">is</span><span class="sc24"> </span><span class="sc16">${parameter[2].age}</span><span
                    class="sc24"> </span><span class="sc0">years</span><span class="sc24"> </span>
                <span class="sc0">old.</span><span class="sc24"> </span>
            </div>
            <p>
                        参数文件
    "parameter.csv":</p>
            <div class="sc99">
                name,age<br />
                WAKU,29<br />
                Joey,2</div>
            <p>
                        输出结果:
    </p>
            <div class="sc99">
                WAKU is 29 years old.<br />
                Joey is 2 years old.</div>
            <p>
                        因为CSV文件没有类似XML文件的根元素,所以SmartText将CSV参数文件的文件名做为每个变量的前缀.<br />
        示例中,因为CSV参数文件的文件名是parameter,所以前缀的名称也是parameter<br />
        使用下标方式访问CSV文件第一行的方式就变成了parameter[1](Lua的数组下标从1开始),<br />
        而访问该行name列中的内容就变成了parameter[1].name,很简单.<br />
    
            </p>
            <div class="detail">
                <ul>
                            <li>技术细节:</li><br />
        实际上parameter已经变成了Lua中的Table.<br />
        SmartText将CSV参数文件解析成嵌套的Table,<br />
        CSV文件除了第一行header以外每行都解析成Table中的一个子Table.<br />
        示例中的CSV解析完的Lua代码如下:
    
                    <br />
                    parameter&nbsp;=&nbsp;<br />
                    {<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;{<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['name']&nbsp;=&nbsp;'WAKU',<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['age']&nbsp;=&nbsp;29,<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;},<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;{<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['name']&nbsp;=&nbsp;'Joey',<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['age']&nbsp;=&nbsp;2,<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;},<br />
                    }<br />
                </ul>
            </div>
            <p>
                        上面的示例虽然能很好的工作,但是模板却略显笨拙,<br />
        使用范型for,你完全可以使用以下的模板形式得到完全一样的输出结果:
    
            </p>
            <div class="sc99">
                <span class="sc17">#{for p in enum(parameter) do}</span><span class="sc24"> </span>
                <br />
                <span class="sc16">${p.name}</span><span class="sc24"> </span><span class="sc0">is</span><span
                    class="sc24"> </span><span class="sc16">${p.age}</span><span class="sc24">
                </span><span class="sc0">years</span><span class="sc24"> </span><span class="sc0">old.</span><br />
                <span class="sc24"></span><span class="sc17">#{end}</span></div>
            <p>
                        值得一提的是,SmartText使用LumenWorks解析CSV文件,LumenWorks是我认为.Net中最棒的CSV解析器.
    
            </p>
            <br />
            <a name="xml">XML参数文件</a>
            <p>
                        XML文件是非常流行的文件格式,有着良好的兼容性,树状的关系最适合表现具有层级关系的数据结构.<br />
        .Net中对XML也有非常完善的支持,你可以将一个.Net对象序列化为XML文件,可以将DataSet对象直接写入XML文件等等.<br />
        XML参数文件的缺点可能是文件内容有些冗长,没有合适的工具的话编辑也有些麻烦.<br />
        同CSV参数文件一样,SmartText把XML参数文件也解析为Lua代码.
    
            </p>
            <h3>
                        示例:
    </h3>
            <p>
                        模板文件:
    </p>
            <div class="sc99">
                <span class="sc17">#{for p in enum(list.person) do}</span><br />
                <span class="sc24"></span><span class="sc16">${p.name}</span><span class="sc24">
                </span><span class="sc0">is</span><span class="sc24"> </span><span class="sc16">${p.age}</span><span
                    class="sc24"> </span><span class="sc0">years</span><span class="sc24"> </span>
                <span class="sc0">old.</span><br />
                <span class="sc24"></span><span class="sc16">${p.name}</span><span class="sc24">
                </span><span class="sc0">likes</span><span class="sc24"> </span><span class="sc16">${join(p.favourite_food.food)}</span><span
                    class="sc0">.</span>
                <br />
                <span class="sc17">#{end}</span>
            </div>
            <p>
                        参数文件
    "parameter.xml":</p>
            <div class="sc99">
                &lt;list&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&lt;person<span class="sc3">&nbsp;name</span><span class="sc8">=</span><span
                    class="sc6">"WAKU"</span><span class="sc8">&nbsp;</span><span class="sc3">age</span><span
                        class="sc8">=</span><span class="sc6">"29"</span>&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;favourite_food&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;food&gt;<span
                    class="sc0">rice</span>&lt;/food&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;food&gt;<span
                    class="sc0">chicken</span>&lt;/food&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/favourite_food&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&lt;/person&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&lt;person<span class="sc3">&nbsp;name</span><span class="sc8">=</span><span
                    class="sc6">"Joey"</span><span class="sc8">&nbsp;</span><span class="sc3">age</span><span
                        class="sc8">=</span><span class="sc6">"2"</span>&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;favourite_food&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;food&gt;<span
                    class="sc0">milk</span>&lt;/food&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;food&gt;<span
                    class="sc0">juice</span>&lt;/food&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;food&gt;<span
                    class="sc0">candy</span>&lt;/food&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/favourite_food&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&lt;/person&gt;<br />
                &lt;/list&gt;<br />
            </div>
            <p>
                        输出结果:
    </p>
            <div class="sc99">
                WAKU is 29 years old.<br />
                WAKU likes rice,chicken.<br />
                Joey is 2 years old.<br />
                Joey likes milk,juice,candy.<br />
            </div>
            <p>
                        这个示例演示了如何正确的在模板中引用XML参数中的内容.<br />
        只需记住几个简单的规则:<br />
        1.变量从根节点开始(示例中根节点为list)<br />
        2.使用点(.)引用Attribute(示例中的name和age)<br />
        3.同样使用点(.)引用子节点<br />
        4.如果一个节点出现多次,则它就是一个数组,可以使用enum函数枚举(示例中的person和food)<br />
        <br />
        示例的模板中出现了一个新函数join,和enum一样它也是由SmartText提供的.<br />
        作用是将一个数组中的字符串元素拼接起来,调用时第一个参数与enum一样(.Net的数组,集合或者Lua的Table);第二个参数可选,即拼接时的分隔符,默认是一个逗号(,).<br />
    
            </p>
            <div class="detail">
                <ul>
                            <li>技术细节:</li><br />
        示例中的XML解析完的Lua代码如下:
    
                    <br />
                    list&nbsp;=&nbsp;<br />
                    {<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;['person']&nbsp;=&nbsp;<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;{<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['name']&nbsp;=&nbsp;'WAKU',<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['age']&nbsp;=&nbsp;29,<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['favourite_food']&nbsp;=&nbsp;<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['food']&nbsp;=&nbsp;<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'rice',<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'chicken',<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['name']&nbsp;=&nbsp;'Joey',<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['age']&nbsp;=&nbsp;2,<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['favourite_food']&nbsp;=&nbsp;<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['food']&nbsp;=&nbsp;<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'milk',<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'juice',<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'candy',<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br />
                    &nbsp;&nbsp;&nbsp;&nbsp;},<br />
                    }<br />
                </ul>
            </div>
            <a name="lua">LUA参数文件</a>
            <p>
                        Lua参数文件在三种参数文件中效率最高(因为CSV和XML都需要先解析为Lua代码),而且也是最灵活的一个.<br />
        它的缺点是没有CSV和XML那么流行,并且使用它需要掌握一定的Lua知识.<br />
        使用Lua参数文件完全可以实现之前CSV和XML的示例(直接使用技术细节中的Lua代码做为参数文件即可)<br />
        而Lua参数文件有些东西却是CSV和XML做不到的.
    </p>
                <h3>
                            示例:
    </h3>
                <p>
                            模板文件:
    </p>
                <div class="sc99">
                    <span class="sc0">a</span><span class="sc24"> </span><span class="sc0">=</span><span
                        class="sc24"> </span><span class="sc16">${a}</span><br />
                    <span class="sc24"></span><span class="sc0">b</span><span class="sc24"> </span><span
                        class="sc0">=</span><span class="sc24"> </span><span class="sc16">${b}</span><br />
                    <span class="sc24"></span><span class="sc0">c</span><span class="sc24"> </span><span
                        class="sc0">=</span><span class="sc24"> </span><span class="sc16">${c}</span><br />
                    <span class="sc24"></span><span class="sc0">a</span><span class="sc24"> </span><span
                        class="sc0">+</span><span class="sc24"> </span><span class="sc0">b</span><span class="sc24">
                        </span><span class="sc0">+</span><span class="sc24"> </span><span class="sc0">c</span><span
                            class="sc24"> </span><span class="sc0">=</span><span class="sc24"> </span>
                    <span class="sc16">${a + b + c}</span>
                </div>
                <p>
                            参数文件
    "parameter.lua":</p>
                <div class="sc99">
                    <span class="sc11">a</span><span class="sc0"> </span><span class="sc10">=</span><span
                        class="sc0"> </span><span class="sc4">1</span><br />
                    <span class="sc0"></span><span class="sc11">b</span><span class="sc0"> </span><span
                        class="sc10">=</span><span class="sc0"> </span><span class="sc4">2</span><br />
                    <span class="sc0"></span><span class="sc11">c</span><span class="sc0"> </span><span
                        class="sc10">=</span><span class="sc0"> </span><span class="sc4">3</span></div>
    </div>
    <p>
                输出结果:
    </p>
    <div class="sc99">
        a = 1<br />
        b = 2<br />
        c = 3<br />
        a + b + c = 6
    </div>
    <p>
                如果使用CSV或者XML的话,模板中则不得不引用CSV的文件名或者XML的根节点名称,<br />
        参数文件也需要使用逗号或者放到XML的TAG中,而使用Lua参数文件则非常简单,直接赋值即可.<br />
        不过要注意的是,这些变量全被定义为Lua的全局变量,所以在使用的时候要注意命名冲突的问题.<br />
        当然如果变量非常多的话,则应该使用Lua的Table把变量组织起来.
    
    </p>
    <br />
    <hr />
    <h2>
        <a name="error handling">错误处理</a></h2>
    <p>
                如果在生成文本时产生错误,SmartText会将错误信息以红色字体显示到文本框中.
    
    </p>
    <h3>
        <a name="lua error">Lua错误</a></h3>
    <p>
                SmartText将模板内容解析为Lua代码,所以模板应当符合Lua的语法要求,否则Lua的编译器就会报错,<br />
        另外一种就是模板没有语法错误,但是做为Lua代码运行时发生了运行时错误,<br />
        无论哪种错误,SmartText都会将错误信息截取并显示到文本框中.<br />
        看下面的例子:
    
    </p>
    <div class="sc99">
        <span class="sc17">#{for i = 1, 5}<br />
        </span><span class="sc0">i = </span><span class="sc16">${i}</span><br />
        <span class="sc17">#{end}</span></div>
    <br />
    <p>
                该模板不需要参数文件即可运行,但是运行时SmartText会显示如下:
    </p>
    <img src="Images/error_chinese.jpg" />
    <p>
                文本框中第一行是Lua编译器的错误信息,编译错误的格式为[string "chunk"]:<i>line</i>:<br />
        其中的line即是Lua代码中出错的行号.后面的内容是详细的错误描述,即缺少do.<br />
        第2行以下,就是根据模板解析生成的Lua代码,为了便于查看,SmartText在每行代码前添加了行号.<br />
        <br />
        从输出的Lua代码中我们可以看出SmartText在解析模板时的一些处理细节:<br />
        1.流程控制#{...}中的内容直接被解析为Lua代码.(示例中的for和end语句);<br />
        2.RenderText是SmartText内部使用的一个函数,用来返回最终生成的文本;<br />
        3.使用 [=[ 和 ]=] 表示普通的字符串,防止其中的内容被转义;<br />
        4.Lua代码的最后一行return 0是SmartText固定添加的
    
    </p>
    <h3>
        <a name="undefine variable">未定义变量错误</a></h3>
            当使用参数中不存在的变量时,会发生该错误.比如下面的模板:<br />
    
    <br />
    <div class="sc99">
        <span class="sc16">${a}</span><span class="sc0"> + </span><span class="sc16">${b}</span><span
            class="sc0"> + </span><span class="sc16">${c}</span></div>
    <br />
    <p>
                如果不使用任何参数文件,该模板会产生如下错误:
    
    </p>
    <div class="error">
        [string&nbsp;"chunk"]:1:&nbsp;attempt&nbsp;to&nbsp;concatenate&nbsp;global&nbsp;'c'&nbsp;(a&nbsp;nil&nbsp;value)<br />
        Lua&nbsp;Source:<br />
        &nbsp;&nbsp;1&nbsp;:&nbsp;RenderText(1,&nbsp;[=[]=]&nbsp;..&nbsp;(a)&nbsp;..&nbsp;[=[&nbsp;+&nbsp;]=]&nbsp;..&nbsp;(b)&nbsp;..&nbsp;[=[&nbsp;+&nbsp;]=]&nbsp;..&nbsp;(c)&nbsp;..&nbsp;[=[]=],&nbsp;'\r\n');&nbsp;<br />
        &nbsp;&nbsp;2&nbsp;:&nbsp;return&nbsp;0<br />
    </div>
    <p>
                错误信息中明确的指出了哪个变量不存在,和该变量在代码中出现的位置.
    
    </p>
    <p>
                另外,如果指定了参数文件, SmartText还会将参数文件解析成的Lua代码添加到文本框的最后,以便分析错误.
    
    </p>
    <br />
    <hr />
    <h2>
        <a name="command line">命令行参数</a></h2>
    <p>
                SmartText可以使用命令行参数,格式如下:
    
    </p>
    <div class="sc99" style="font-size: small">
        SmartText.exe <i>template</i> [<i>parameter</i> [<i>output</i> [<i>template encoding</i>
        [<i>parameter encoding</i> [<i>output encoding</i>]]]]]
    </div>
    <p>
                分别对应模板文件,参数文件,输出文件,模板文件编码,参数文件编码和输出文件编码.<br />
        其中模板文件是必须项, 其它都可以省略.<br />
        第4到6个参数要求是编码的CODE PAGE(一个整数),可通过SmartText设定窗口中的各编码的下拉框查询编码的CODE PAGE.<br />
        下面是一个使用命令行参数的示例:
    
    </p>
    <div class="sc99" style="font-size: small">
        SmartText.exe "d:\template.txt" "" "d:\output.txt" 936 0 65001
    </div>
    <p>
                使用d:\template.txt做为模板文件,不使用参数文件,使用d:\output.txt做为输出文件,模板文件的编码为GB2312,输出文件的编码为UTF-8.
    
    </p>
    <p>
                当调用成功,输出文件就会被生成,除此之外没有任何提示,另外SmartText的返回值为0<br />
        如果调用失败,SmartText的GUI会显示出来,可通过<a href="#error handling">错误处理</a>中介绍的方法查看是哪出了问题.
    
    </p>
</body>
</html>

